package com.kl.controller;

import com.kl.model.ErrMessage;
import com.kl.model.Token;
import com.kl.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

@Controller
public class CoreController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${weixin.pc.appid}")
    private String appid;

    @Value("${weixin.pc.appsecret}")
    private String appsecret;

    @Value("${weixin.callbackurl}")
    private String callBack;

    @Value("${weixin.pc.scope}")
    private String scope;

    @Value("${weixin.pc.responsetype}")
    private String responseType;

    @Autowired
    private RestTemplate restTemplate;

    // 生成授权地址，让用户点击扫码登录
    @RequestMapping("/index-official")
    public String indexOfficial(Model model) throws UnsupportedEncodingException {
        String oauthUrl = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
        String redirect_uri = URLEncoder.encode(callBack, "utf-8");
        oauthUrl = oauthUrl
                .replace("APPID", appid)
                .replace("REDIRECT_URI", redirect_uri).replace("SCOPE", scope)
                .replace("code", responseType);

        model.addAttribute("name", " lkl");
        model.addAttribute("oauthUrl", oauthUrl);
        return "index-official";
    }


    // 自定义二维码页面
    @RequestMapping("/")
    public String index(Model model) throws UnsupportedEncodingException {
        String redirect_uri = URLEncoder.encode(callBack, "utf-8");
        model.addAttribute("name", "lkl");
        model.addAttribute("appid", appid);
        model.addAttribute("scope", scope);
        model.addAttribute("redirect_uri", redirect_uri);
        return "index";
    }


    // 用户授权成功后的回调方法，并会在方法后带上code和state参数：redirect_uri?code=CODE&state=STATE
    // 若用户禁止授权，则重定向后不会带上code参数，仅会带上state参数：redirect_uri?state=STATE
    @RequestMapping("/callBack")
    public String callBack(String code, String state, Model model) throws Exception {
        logger.info("进入授权回调,code:{},state:{}", code, state);
        if (code == null) {
            throw new RuntimeException("用户禁止授权");
        }
        //====用户同意授权====
        try {
            // 1.先通过code获取access_token
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={APPID}&secret={SECRET}&code={CODE}&grant_type=authorization_code";
            Map<String, String> tokenParams = new HashMap<>();
            tokenParams.put("APPID", appid);
            tokenParams.put("SECRET", appsecret);
            tokenParams.put("CODE", code);
            Token token = restTemplate.getForObject(url, Token.class, tokenParams);
            if (token == null) {
                ErrMessage errMsg = restTemplate.getForObject(url, ErrMessage.class, tokenParams);
                model.addAttribute("errMsg", errMsg);
                logger.info("errMsg = {}", errMsg);
                throw new RuntimeException("code参数错误");
            }
            // 2.再通过access_token和openid获取用户信息
            String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token={ACCESS_TOKEN}&openid={OPENID}";
            Map<String, String> userParams = new HashMap<>();
            userParams.put("ACCESS_TOKEN", token.getAccess_token());
            userParams.put("OPENID", token.getOpenid());
            User user = restTemplate.getForObject(userInfoUrl, User.class, userParams);

            model.addAttribute("token", token);
            model.addAttribute("user", user);

            logger.info("Token信息 = {}", token);
            logger.info("User信息 = {}", user);
        } catch (RestClientException e) {
            e.printStackTrace();
        }
        return "result";
    }

}
